﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Graphic = Ribbon.Core.Graphics.GraphicHelper;
using Ribbon.Core.Menu;
using System.ComponentModel;

namespace Ribbon.Core
{
    public class Ribbon : Control, IComponent, IDisposable
    {
        public new static Font DefaultFont = new Font("微软雅黑", 9.5f);

        private float tempEmptyX = 5;

        public float TempEmptyX { get { return tempEmptyX; } set { tempEmptyX = value; } }

        public Ribbon()
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

            this.SetStyle(ControlStyles.UserPaint, true);

            Pages = new RibbonPageCollection(this);

            Dock = DockStyle.Top;

            Size = new Size(100, 90);

            Location = new Point(0, 0);

            BackColor = Color.FromArgb(238, 238, 242);

            BorderColor = Color.FromArgb(209, 209, 209);

            ForeColor = Color.FromArgb(61, 64, 77);

            TabForeground = Color.FromArgb(61, 64, 77);

            SelectTabForeground = Color.FromArgb(255, 255, 255);

            SelectTabBackground = Color.FromArgb(83, 173, 83);

            Font = new Font("微软雅黑", 9.5f);

            DefaultFont = Font;

            tabHeight = 20;

            Graphic.CreateGraphics(this);
        }

        [DefaultValue(false)]
        private bool Initialized;

        public void Initialize()
        {
            Initialized = false;
        }

        public void EndInitialize()
        {
            Initialized = true;

            this.Refresh();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (Initialized == false) return;

            Graphic.Dispose();
        }

        ~Ribbon()
        {
            Graphic.Dispose();
        }

        private int tabHeight = 20;

        public int TabHeight
        {
            get { return tabHeight; }
            set
            {
                tabHeight = value;
            }
        }

        private Font font;

        public override Font Font
        {
            get
            {
                return font;
            }
            set
            {
                font = value;

                if (value != null)
                {
                    foreach (RibbonPageBase pg in this.Pages)
                    {
                        if (pg.Font == null)
                        {
                            pg.Font = this.font;
                        }
                    }
                }
            }
        }

        public int BorderSize { get; set; }

        public Color BorderColor { get; set; }

        public Color SelectTabBackground { get; set; }

        public Color SelectTabForeground { get; set; }

        public Color TabBackground { get; set; }

        public Color TabForeground { get; set; }

        public RibbonPageCollection Pages { get; private set; }

        public RibbonPage ActivePage { get; set; }

        private RibbonPageBase HoverPage { get; set; }

        private IRibbonItem HoverItem { get; set; }

        protected override void OnPaint(PaintEventArgs e)
        {
            //Graphics g;

            Graphic.Graphics.Clear(this.BackColor);

            //Draw Base

            //Draw Page Hearder
            foreach (RibbonPageBase page in Pages)
            {
                page.OnPaint(Graphic.Graphics);
            }

            //Draw Split Line
            using (Pen p = new Pen(BorderColor, 1f))
            {
                Graphic.Graphics.DrawLine(p, 2, TabHeight, this.Width - 4, TabHeight);
            }

            Graphic.Buffer.Render(e.Graphics);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (!Initialized) return;

            if (e.Y > TabHeight)
            {
                if (ActivePage != null)
                {
                    IRibbonItem item = null;

                    foreach (var group in ActivePage.Groups)
                    {
                        if (group.GroupRect.Contains(e.Location))
                        {
                            foreach (var _item in group.Items)
                            {
                                if (_item.Rect.Contains(e.Location))
                                {
                                    item = _item;
                                }
                            }
                        }
                    }

                    if (item != null)
                    {
                        if (HoverItem != null)
                        {
                            if (item == HoverItem)
                            {
                                HoverItem.OnMouseMove(e);

                                return;
                            }
                            else
                            {
                                HoverItem.OnMouseLeave(e);

                                HoverItem.IsMouseHover = false;

                                HoverItem.OnMouseEnter(e);

                                HoverItem = item;

                                HoverItem.IsMouseHover = true;
                            }
                        }
                        else
                        {
                            item.OnMouseEnter(e);

                            HoverItem = item;

                            HoverItem.IsMouseHover = true;
                        }
                    }
                    else
                    {
                        if (HoverItem == null)
                            return;
                        else
                        {
                            HoverItem.OnMouseLeave(e);
                            HoverItem.IsMouseHover = false;
                            HoverItem = null;
                        }
                    }
                }
                else
                {
                    return;
                }
            }
            else
            {
                RibbonPageBase tempPage = null;

                foreach (RibbonPageBase page in Pages)
                {
                    if (page.Rect.Contains(e.Location))
                    {
                        tempPage = page;
                    }
                }

                if (tempPage != null)
                {
                    if (HoverPage != null)
                    {
                        if (HoverPage == tempPage)
                            return;

                        HoverPage.IsMouseHover = false;
                    }

                    HoverPage = tempPage;

                    HoverPage.IsMouseHover = true;
                }
                else
                {
                    if (HoverPage != null)
                    {
                        HoverPage.IsMouseHover = false;
                        HoverPage = null;
                    }
                    else
                    {
                        return;
                    }
                }
            }

            this.Refresh();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (!Initialized) return;

            if (e.Y > TabHeight)
            {
                if (HoverItem != null)
                {
                    HoverItem.OnMouseDown(e);
                }
            }
            else
            {
                RibbonPageBase tempPage = null;

                foreach (RibbonPageBase page in Pages)
                {
                    if (page.Rect.Contains(e.Location))
                    {
                        tempPage = page;
                    }
                }

                if (tempPage != null)
                {
                    if (tempPage is RibbonPage)
                    {
                        if (ActivePage != null)
                        {
                            ActivePage.IsActive = false;
                        }

                        var page = tempPage as RibbonPage;

                        page.IsActive = true;

                        page.IsMouseHover = true;

                        ActivePage = page;

                        this.Focus();
                    }
                    else if (tempPage is RibbonPageButton)
                    {
                        var page = tempPage as RibbonPageButton;

                        page.IsMouseHover = true;

                        page.OnMouseDown(e);

                        this.Focus();
                    }

                    else if (tempPage is RibbonMenu)
                    {
                        var page = tempPage as RibbonMenu;

                        page.IsMouseHover = true;

                        page.OnMouseDown(e);
                    }
                }

                this.Refresh();
            }
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            if (HoverItem != null)
            {
                this.HoverItem.OnMouseLeave(new MouseEventArgs(System.Windows.Forms.MouseButtons.None, 1, 1, 1, 1));
                HoverItem.IsMouseHover = false;
                HoverItem = null;
            }

            if (HoverPage != null)
            {
                HoverPage.IsMouseHover = false;
                HoverPage = null;
                this.Refresh();
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this.Refresh();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            if (this.HoverItem != null)
            {
                this.HoverItem.OnMouseLeave(new MouseEventArgs(System.Windows.Forms.MouseButtons.None, 1, 1, 1, 1));
                this.HoverItem.IsMouseHover = false;
                this.HoverItem = null;
            }

            else if (this.HoverPage != null)
            {
                this.HoverPage.IsMouseHover = false;
                this.HoverPage = null;
            }
            base.OnLostFocus(e);
        }
    }
}
